package com.xuebusi.ribbon.loadbalance.consumer.service.impl;

import com.xuebusi.ribbon.loadbalance.consumer.entity.Product;
import com.xuebusi.ribbon.loadbalance.consumer.service.OrderService;
import com.xuebusi.ribbon.loadbalance.consumer.vo.ResultVO;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;

@Service
public class OrderServiceImpl implements OrderService {
    @Resource
    private RestTemplate restTemplate;

    /**
     * 查询商品信息
     *
     * @param productId 商品id
     * @return
     */
    @Override
    public ResultVO<Product> findProductById(Long productId) {
        // Ribbon通过服务名称的方式调用远程服务，会开启负载均衡，默认使用轮询的方式调用服务;
        // 当不同机器上的微服务配置了相同的spring.application.name名称，
        // Ribbon会使用该服务名称在不同的主机地址之间进行负载均衡;
        // 注意：使用ribbon实现负载均衡的时候，服务名称不能用下划线，换成中划线;
        // 由于在创建RestTemplate实例的时候已经使声明了@LoadBalanced注解
        // 下面可以直接使用服务名称调用远程微服务，不需要使用IP地址+端口来拼接URL;
        // 例如下面URL中的ribbon-load-balance-provider就是注册到eureka注册中心的服务名称
        String url = "http://ribbon-load-balance-provider/product/1";
        ParameterizedTypeReference<ResultVO<Product>> reference = new ParameterizedTypeReference<ResultVO<Product>>() {
        };
        ResponseEntity<ResultVO<Product>> responseEntity = restTemplate
                .exchange(url, HttpMethod.GET, null, reference);
        return responseEntity.getBody();
    }
}
